//
//  PresentationModalController.m
//  CKApp
//
//  Created by CC on 2020/9/6.
//  Copyright © 2020 This Moment. All rights reserved.
//

#import "PresentationModalController.h"
#import "LcFoundation.h"
#import "BaseViewController.h"
#import "PresentationModalConfig.h"
#import "Masonry.h"
#import "PresentationController.h"

@interface PresentationModalController ()
@property(nonatomic, assign) BOOL isTapEnabled;
@property(nonatomic, assign) BOOL isPanEnabled;
@property(nonatomic, assign) BOOL useBottomEdge;
@property(nonatomic, assign) BOOL customOrientation;
@property(nonatomic, assign) BOOL customShouldAutorotate;
@property(nonatomic, assign) UIInterfaceOrientationMask customSupportedOrientations;
@property(nonatomic, strong) OnClickedHandler closeByGestureRecognizerHandler;

@property(nonatomic, assign) CGFloat transOriginY;
@property(nonatomic, strong) UIView* panelInnerView;
@property(nonatomic, assign) CGFloat panelOriginHeight;
@property(nonatomic, assign) BOOL transWillEnd;
@property(nonatomic, assign) BOOL transBounce;
@property(nonatomic, assign) BOOL transDragUp;
@property(nonatomic, assign) BOOL transDragDown;

@property(nonatomic, strong) UIImageView* bgImageView;
@property(nonatomic, strong) UIImage* bgImage;
@property(nonatomic, strong) UIColor* rootBackgroundColor;

@property(nonatomic, assign) CGFloat cellContentHeight;
@end

@implementation PresentationModalController

- (void)viewDidLoad {
  [super viewDidLoad];
  LC_CHECK_NOT_NULL(self.panelContainer);
  [self setUp];
}

//- (void)viewWillAppear:(BOOL)animated {
//  [super viewWillAppear:animated];
//  [[NSNotificationCenter defaultCenter] addObserver:self
//                                           selector:@selector(keyboardWillShowNSNotification:)
//                                               name:UIKeyboardWillShowNotification
//                                             object:nil];
//  [[NSNotificationCenter defaultCenter] addObserver:self
//                                           selector:@selector(keyboardWillHideNotification:)
//                                               name:UIKeyboardWillHideNotification
//                                             object:nil];
//}
//
//- (void)viewWillDisappear:(BOOL)animated {
//  [super viewWillDisappear:animated];
//  [[NSNotificationCenter defaultCenter] removeObserver:self
//                                                  name:UIKeyboardWillShowNotification
//                                                object:nil];
//  [[NSNotificationCenter defaultCenter] removeObserver:self
//                                                  name:UIKeyboardWillHideNotification
//                                                object:nil];
//}

- (void)viewDidLayoutSubviews {
  [self.panelView clearCorner];
  [self.panelView setCorner:UIRectCornerTopLeft | UIRectCornerTopRight cornerRaius:15.0];
}

- (void)setUp {
  self.isTapEnabled = YES;
  self.isPanEnabled = YES;
  self.useBottomEdge = YES;
  self.panelMaxHeight = LcUIUtility.screenHeight - LcUIUtility.statusBarHeight;
  self.customSupportedOrientations = UIInterfaceOrientationPortrait;
  self.rootBackgroundColor = [UIColor whiteColor];

  self.panelView = [[UIView alloc] init];
  [self.view addSubview:self.panelView];
  self.panelView.backgroundColor = [UIColor whiteColor];

  [self.panelView mas_makeConstraints:^(MASConstraintMaker* make) {
    make.bottom.left.right.height.equalTo(self.view);
  }];
//  self.bgImageView = [[UIImageView alloc] initWithImage:self.bgImage];
//  self.bgImageView.contentMode = UIViewContentModeScaleAspectFit;
//  self.bgImageView.clipsToBounds = YES;
//  [self.panelView addSubview:self.bgImageView];
//
//  [self.bgImageView mas_makeConstraints:^(MASConstraintMaker* make) {
//    make.top.left.right.equalTo(self.panelView);
//    make.height.equalTo(self.view);
//  }];
//
//  [self.bgImageView setHidden:self.bgImage == nil];

  self.panelInnerView = [[UIView alloc] init];
  self.panelInnerView.backgroundColor = [UIColor whiteColor];
  [self.panelView addSubview:self.panelInnerView];
  [self.panelInnerView mas_makeConstraints:^(MASConstraintMaker* make) {
    make.top.left.right.equalTo(self.panelView);
    make.height.equalTo(self.view);
  }];

  if (self.panelContainer != nil) {
    self.panelContainer.fromViewController = self;
    self.panelContainer.view.frame = self.panelInnerView.bounds;
    [self.panelInnerView addSubview:self.panelContainer.view];
    [self.panelContainer.view mas_makeConstraints:^(MASConstraintMaker *make) {
      make.edges.equalTo(self.panelInnerView);
    }];
  }

  UITapGestureRecognizer* tapGesture =
  [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTapAction:)];
  tapGesture.delegate = self;
  [tapGesture setEnabled:self.isTapEnabled];
  [self.view addGestureRecognizer:tapGesture];

  UIPanGestureRecognizer* panGesture =
  [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
  [panGesture setEnabled:self.isPanEnabled];
  [self.view addGestureRecognizer:panGesture];
}

- (CGFloat)bottomEdge {
  return self.useBottomEdge ? PRESENTATION_BOTTOMEDGE : 0.0;
}

- (void)springWithDampingAnimation:(CGPoint)translation {
  [UIView animateWithDuration:0.25
      delay:PRESENTATION_DELAY
      usingSpringWithDamping:PRESENTATION_SPRINGWITHDAMPING
      initialSpringVelocity:PRESENTATION_SPRINGVELOCITY
      options:UIViewAnimationOptionCurveEaseInOut
      animations:^{
        if (self.transDragDown) {
          if (self.transWillEnd) {
            [self updatePanelViewHeight:0.0 isOriginHeight:NO isLimitHeight:NO];
            self.presentationCtrl.backgroundView.alpha = 0.0;
          } else {
            [self updatePanelViewHeight:self.panelOriginHeight isOriginHeight:NO isLimitHeight:NO];
            self.presentationCtrl.backgroundView.alpha = 1.0;
          }
        } else {
          self.panelView.transform =
              CGAffineTransformMakeTranslation(0, self.panelView.height - self.panelOriginHeight);
        }
        [self.view layoutIfNeeded];
      }
      completion:^(BOOL finished) {
        if (self.transDragUp) {
          self.panelView.transform = CGAffineTransformIdentity;
        }
      }];
}

- (void)updatePanelViewHeight:(CGFloat)newHeight
               isOriginHeight:(BOOL)isOriginHeight
                isLimitHeight:(BOOL)isLimitHeight {
  if (isOriginHeight) {
    CGFloat realyNewHeight = newHeight + [self bottomEdge] + [LcUIUtility bottomSafeAreaHeight];
    if (isLimitHeight) {
      self.panelMaxHeight = MIN(self.panelMaxHeight, realyNewHeight);
    }
    CGFloat originHeight = MIN(self.panelMaxHeight, realyNewHeight);
    self.panelOriginHeight = originHeight;
    [self.panelInnerView mas_updateConstraints:^(MASConstraintMaker* make) {
      make.height.mas_equalTo(MIN(newHeight, self.panelMaxHeight));
    }];

    [self.panelView mas_remakeConstraints:^(MASConstraintMaker *make) {
      make.bottom.left.right.equalTo(self.view);
      make.height.mas_equalTo(originHeight);
    }];
//
//    [self.bgImageView mas_updateConstraints:^(MASConstraintMaker* make) {
//      make.height.mas_equalTo(originHeight);
//    }];
  } else {
    CGFloat originHeight = MIN(self.panelMaxHeight, newHeight);
    [self.panelView mas_updateConstraints:^(MASConstraintMaker* make) {
      make.height.mas_equalTo(originHeight);
    }];
  }
  [self.view layoutIfNeeded];
}
//
//- (void)addBackgroundImage:(UIImage*)image {
//  [self updateBackgroundImage:image];
//}
//
//- (void)updateBackgroundImage:(UIImage*)image {
//  self.bgImage = image;
//  [self.bgImageView setHidden:NO];
//  self.bgImageView.image = image;
//}
//
//- (void)updateBackgroundImageEdgeInsets:(UIEdgeInsets)edge {
//  [self.bgImageView mas_updateConstraints:^(MASConstraintMaker* make) {
//    make.top.equalTo(self.panelView).offset(edge.top);
//    make.left.equalTo(self.panelView).offset(edge.left);
//    make.right.equalTo(self.panelView).offset(edge.right);
//    make.height.mas_equalTo(self.bgImageView.height - edge.top);
//  }];
//}

#pragma mark - Action
- (void)backgroundTapAction:(UITapGestureRecognizer*)tapGesture {
  [self.view endEditing:YES];
  [self closePanel];
}

- (void)panAction:(UIPanGestureRecognizer*)panGesture {
  [self.view endEditing:YES];
  CGPoint velocity = [panGesture velocityInView:panGesture.view];
  CGFloat dismissVelocity = PRESENTATION_VELOCITYCOEFFICIENT * 1000.0;
  if (panGesture == self.scrollView.panGestureRecognizer) {
    if (self.scrollView == nil) {
      return;
    }
    CGSize contentSize = self.scrollView.contentSize;
    CGSize boundSize = self.scrollView.bounds.size;
    CGFloat offsetY = self.scrollView.contentOffset.y;

    if (!self.scrollView.isDecelerating && contentSize.height > boundSize.height) {
      [self.scrollView setBounces:offsetY > PRESENTATION_OFFSETTHRESHOLD];
      if (self.panelView.height < self.panelOriginHeight) {
        [self.scrollView setBounces:NO];
      }
    }

    if (offsetY == 0) {
      [self panelViewHeightTransform:velocity dismissVelocity:dismissVelocity panGestur:panGesture];
    } else if (offsetY + boundSize.height > contentSize.height) {
      if (self.panelView.height < self.panelOriginHeight) {
        LcLog(@"TODO: -if panel view constraint less than panelOriginHeight, add it");
      }
      LcLog(@"TODO: =======bottom=======");
    } else {
      LcLog(@"TODO: =======bottom=======");
      [self panelViewHeightTransform:velocity dismissVelocity:dismissVelocity panGestur:panGesture];
    }
  } else {
    [self panelViewHeightTransform:velocity dismissVelocity:dismissVelocity panGestur:panGesture];
  }
}

- (void)panelViewHeightTransform:(CGPoint)velocity
                 dismissVelocity:(CGFloat)dismissVelocity
                       panGestur:(UIPanGestureRecognizer*)panGesture {
  if (velocity.y > dismissVelocity) {
    [self closePanel];
  } else {
    CGPoint translation = [panGesture translationInView:self.view];
    self.transDragUp = translation.y < 0;
    self.transDragDown = translation.y > 0;
    switch (panGesture.state) {
      case UIGestureRecognizerStateBegan:
        self.transOriginY = CGRectGetMinX(self.panelView.frame);
        break;
      case UIGestureRecognizerStateChanged: {
        CGFloat newTransY = self.transOriginY + self.transOriginY / 2.5;
        CGFloat newPanelHeight = MAX(0, LcUIUtility.screenHeight - newTransY);
        self.presentationCtrl.backgroundView.alpha =
            MIN((newPanelHeight / self.panelOriginHeight), 1.0);
        newPanelHeight = MIN(newPanelHeight, self.panelMaxHeight);
        [self updatePanelViewHeight:newPanelHeight isOriginHeight:NO isLimitHeight:NO];
        if (newPanelHeight <= self.panelOriginHeight / 2.0) {
          self.transWillEnd = YES;
          [self closePanel];
        } else {
          self.transBounce = YES;
        }
      } break;
      case UIGestureRecognizerStateEnded:
      case UIGestureRecognizerStateCancelled:
      case UIGestureRecognizerStateFailed: {
        if (self.transBounce) {
          [self springWithDampingAnimation:translation];
        }
      } break;

      case UIGestureRecognizerStatePossible:
        break;

      default:
        break;
    }
  }
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
  if (gestureRecognizer != nil) {
    CGPoint location = [gestureRecognizer locationInView:self.view];
    if (CGRectContainsPoint(self.panelView.frame, location)) {
      return NO;
    }
  }
  return YES;
}

- (void)closePanel {
  if (self.closeByGestureRecognizerHandler != nil) {
    self.closeByGestureRecognizerHandler(self);
  }
  [self presentationModalDismiss:self.closeHandler];
}

#pragma mark - Notification
- (void)keyboardWillShowNSNotification:(id)notification {
  [self adjustContentViewByKeyboardState:YES keyboardInfo:notification];
}

- (void)keyboardWillHideNotification:(id)notification {
  [self adjustContentViewByKeyboardState:NO keyboardInfo:notification];
}

- (void)adjustContentViewByKeyboardState:(BOOL)show keyboardInfo:(id)keyboardInfo {
  if (keyboardInfo == nil || self.cellContentHeight <= 0) {
    return;
  }
  CGSize keyboardSize = CGSizeZero;
  NSTimeInterval animationDuration = 0.25;
  UIViewAnimationOptions animationOptions = UIViewAnimationOptionBeginFromCurrentState;
  if ([keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey]) {
    keyboardSize = [[keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGSizeValue];
  }
  if ([keyboardInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey]) {
    animationDuration = [[keyboardInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
  }
  if ([keyboardInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey]) {
    animationOptions = [[keyboardInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
  }
  [UIView animateWithDuration:animationDuration delay:0 options:animationOptions animations:^{
    [self.view layoutIfNeeded];
    if (show) {
      [self updatePanelViewHeight:keyboardSize.height + self.cellContentHeight isOriginHeight:NO isLimitHeight:NO];
    } else {
      [self updatePanelViewHeight:self.cellContentHeight isOriginHeight:NO isLimitHeight:NO];
    }
  } completion:^(BOOL finished) {

  }];
}

#pragma mark - Rotation
- (BOOL)shouldAutorotate {
  return self.customOrientation ? self.customShouldAutorotate : [super shouldAutorotate];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
  return self.customOrientation ? self.customSupportedOrientations
                                : [super supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
  return [super preferredInterfaceOrientationForPresentation];
}

@end
